import { VEMesh } from "../very-edge-mesh";
import { VEMeshExample } from "../very-edge-mesh/vemesh-example";
import { Yours } from "./yours";

export class Game {

    private _canvas: HTMLCanvasElement;
    private _engine!: BABYLON.Engine;
    private _scene!: BABYLON.Scene;
    private _fps: HTMLElement;

    constructor(canvasElement: HTMLCanvasElement) {
        this._canvas = canvasElement;
        this._fps = document.getElementById("fpsLabel")!;
    }

    /**
       * 创建场景，并且启动
       */
    public createScene(): Game {

        if (this._engine) {
            this._engine.dispose();
        }
        this._engine = new BABYLON.Engine(this._canvas, true);

        // Resize
        let engine = this._engine;
        window.addEventListener("resize", function () {
            engine.resize();
        });

        // Create a basic BJS Scene object.
        this._scene = new BABYLON.Scene(this._engine);

        // Create a FreeCamera, and set its position to (x:0, y:5, z:-10).
        // let camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5, -10), this._scene);

        let camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 2, Math.PI / 2, 5, BABYLON.Vector3.Zero(), this._scene);
        camera.wheelDeltaPercentage = 0.01;

        // Target the camera to scene origin.
        camera.setTarget(BABYLON.Vector3.Zero());

        // Attach the camera to the canvas.
        camera.attachControl(this._canvas, false);

        // Create a basic light, aiming 0,1,0 - meaning, to the sky.
        let light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), this._scene);

        // // Create a built-in "sphere" shape; with 16 segments and diameter of 2.
        // let sphere = BABYLON.MeshBuilder.CreateSphere('sphere',
        //     { segments: 16, diameter: 2 }, this._scene);

        // // Move the sphere upward 1/2 of its height.
        // sphere.position.y = 1;

        // // Create a built-in "ground" shape.
        // let ground = BABYLON.MeshBuilder.CreateGround('ground',
        //     { width: 6, height: 6, subdivisions: 2 }, this._scene);

        // console.log("启动Babylon引擎，加载场景");
        
        // 在这里可以运行你自己的代码
        // let yourCode: Yours = new Yours(this._scene);
        // yourCode.doSomething();

        // 加载过度动画开
        // engine.displayLoadingUI();

        let that = this;

        // 加载模型名称，可支持obj、babylon
        let importName: string = "mask.obj";


        // 加载scene.babylon场景文件，加载外部导入的模型
        BABYLON.SceneLoader.ImportMesh("", "assets/", importName, this._scene, function (newMeshes) {

            // 加载过度动画关
            // engine.hideLoadingUI();

            console.log("启动Babylon引擎，加载场景");

            newMeshes[0].rotation.y = 100 / 180 * Math.PI;
            const mat = new BABYLON.StandardMaterial('mat', that._scene);
            mat.diffuseColor = BABYLON.Color3.Gray();
            newMeshes[0].material = mat;


            const vemesh = new VEMesh();
            vemesh.babylonToVEMesh(newMeshes[0]);
            console.log("打印整体数据，遍历面元素等可直接访问对应的数组数据");
            console.warn(vemesh);
            console.log("数据结构操作演示");

            const example =  new VEMeshExample();

            console.log("-遍历单个面元素-");
            example.loopFace(vemesh.faces[0]);
            console.log("-获取与某一个顶点为首顶点的所有loops-");
            console.error(example.getLoopsFromVertex(vemesh.vertices[0]));
            console.log("-获取与某一个顶点所有相邻的顶点，不包含自身-");
            console.error(example.getAdjacentVertsFromVertex(vemesh.vertices[0]));
            console.log("-获取包含某个顶点的所有面片-");
            console.error(example.getFacesFromVertex(vemesh.vertices[0]));
            console.log("-获取包含某条loop半边及对偶半边的所有面片元素-");
            console.error(example.getFacesFromLoop(vemesh.loops[0]));
            console.log("-获取与某一面相邻的所有面片，不包含自身-");
            console.error(example.getAdjacentFacesFromFace(vemesh.faces[0]));


            // 在这里可以运行你自己的代码
            let yourCode: Yours = new Yours(that._scene);
            yourCode.doSomething();

        });

        return this;
    }

	/**
	 * 启动渲染循环；
	 */
    public animate(): Game {
        this._engine.runRenderLoop(() => {
            if (this._canvas.width !== this._canvas.clientWidth) {
                this._engine.resize();
            }

            if (this._scene) {
                this._scene.render();
            }

            this.updateFpsPos();

        });
        return this;
    }

	/**
	 * 属性编辑器UI界面控制；
	 */
    public toggleDebug(): Game {
        if (this._engine) {
            // Always showing the debug layer, because you can close it by itself
            var scene = this._engine.scenes[0];
            if (scene.debugLayer.isVisible()) {
                scene.debugLayer.hide();
            }
            else {
                // 此处修改了babylon.d.ts文件
                scene.debugLayer.show({ embedMode: true });
            }
        }
        return this;
    }

    /**
       * 更新fps显示及显示位置
       */
    updateFpsPos(): void {
        if (this._fps) {
            this._fps.style.right = document.body.clientWidth - this._canvas.clientWidth + 20 + "px";
            this._fps.innerHTML = this._engine.getFps().toFixed() + " fps";
        }
    }

}